<#include "macro_.ftl">
package ${packageCode}.${moduleMapperKey}.dao;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.commons.lang3.ArrayUtils;
import lombok.Getter;
import lombok.Setter;
import lombok.NonNull;

import org.joda.time.DateTime;
import org.apache.commons.lang3.StringUtils;
import com.google.common.collect.Maps;

import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;

import com.cardone.common.dto.PaginationDto;
import com.cardone.persistent.CommonDtoAttributes;
import com.cardone.persistent.builder.ModelArgs;
import com.cardone.persistent.builder.ModelBuilder;
import com.cardone.persistent.builder.ModelBuilderUtils;
import com.cardone.persistent.support.JdbcTemplateSupport;
import com.cardone.persistent.support.PaginationArgs;
import ${packageCode}.${moduleMapperKey}.dto.${entityMapper.code}Dto;

/**
 * ${entityMapper.remarks!entityMapper.code}
 *
 * @author ${author!'yaoht'}
 * 
 */
@Getter
@Setter
public class ${entityCode}JdbcDao implements ${entityCode}Dao {
	/**
	 * jdbcDao模板支持
	 */
	private JdbcTemplateSupport jdbcTemplateSupport;
	
	@Override
	@CacheEvict(value = ${entityCode}Dao.BEAN_ID, allEntries = true)
	public void reload() {
	}

	@Override
	@CacheEvict(value = ${entityCode}Dao.BEAN_ID, allEntries = true)
	public int insertByCode(@NonNull ${entityMapper.code}Dto insert${entityMapper.code}, String... insertProperties) {
		final ModelBuilder modelBuilder = ModelBuilderUtils.newModelBuilder(new ModelArgs(ModelBuilder.Constants.insert.stringValue(),
				insert${entityMapper.code}, insertProperties));

		modelBuilder.putTrue(ModelBuilder.Constants.whereAndBetween.stringValue(), CommonDtoAttributes.sysdate.name());
				
		return this.jdbcTemplateSupport.update(SqlIds.insertByCode.id(), modelBuilder.build());
	}
<#if entityMapper.markService>

	@Override
	@CacheEvict(value = ${entityCode}Dao.BEAN_ID, allEntries = true)
	public int insertByCodeOrId(@NonNull ${entityMapper.code}Dto insert${entityMapper.code}) {
		final ModelBuilder modelBuilder = ModelBuilderUtils.newModelBuilder(new ModelArgs(ModelBuilder.Constants.insert.stringValue(),
				insert${entityMapper.code}));

		modelBuilder.putTrue(ModelBuilder.Constants.whereAndBetween.stringValue(), CommonDtoAttributes.sysdate.name());
				
		return this.jdbcTemplateSupport.update(SqlIds.insertByCode.id(), modelBuilder.build());
	}

	@Override
	@CacheEvict(value = ${entityCode}Dao.BEAN_ID, allEntries = true)
	public int insertByName(@NonNull ${entityMapper.code}Dto insert${entityMapper.code}) {
		final ModelBuilder modelBuilder = ModelBuilderUtils.newModelBuilder(new ModelArgs(ModelBuilder.Constants.insert.stringValue(),
				insert${entityMapper.code}));

		modelBuilder.putTrue(ModelBuilder.Constants.whereAndBetween.stringValue(), CommonDtoAttributes.sysdate.name());

		return this.jdbcTemplateSupport.update(SqlIds.insertByName.id(), modelBuilder.build());
	}
</#if>

	@Override
	@CacheEvict(value = ${entityCode}Dao.BEAN_ID, allEntries = true)
	public int deleteByCode(@NonNull ${entityMapper.code}Dto delete${entityMapper.code}, String... whereAndEqProperties) {
		final ModelBuilder modelBuilder = ModelBuilderUtils.newModelBuilder(new ModelArgs(delete${entityMapper.code},
				whereAndEqProperties));

		if (!(ArrayUtils.contains(whereAndEqProperties, CommonDtoAttributes.beginDate.name()) || ArrayUtils
				.contains(whereAndEqProperties, CommonDtoAttributes.endDate.name()))) {
			modelBuilder.putTrue(ModelBuilder.Constants.whereAndBetween.stringValue(), CommonDtoAttributes.sysdate.name());
		}

		return this.jdbcTemplateSupport.update(SqlIds.deleteByCode.id(), modelBuilder.build());
	}
<#if entityMapper.markService>

	@Override
	@CacheEvict(value = ${entityCode}Dao.BEAN_ID, allEntries = true)
	public int deleteByCodeOrId(@NonNull ${entityMapper.code}Dto delete${entityMapper.code}) {
		final ModelBuilder modelBuilder = ModelBuilderUtils.newModelBuilder(new ModelArgs(delete${entityMapper.code}));

		modelBuilder.putTrue(ModelBuilder.Constants.whereAndBetween.stringValue(), CommonDtoAttributes.sysdate.name());

		return this.jdbcTemplateSupport.update(SqlIds.deleteByCode.id(), modelBuilder.build());
	}
	
	@Override
	@CacheEvict(value = ${entityCode}Dao.BEAN_ID, allEntries = true)
	public int deleteByIds(@NonNull ${entityMapper.code}Dto delete${entityMapper.code}) {
		ModelBuilder modelBuilder = ModelBuilderUtils.newModelBuilder();
		
		modelBuilder.put(new String[]{DtoAttributes.ids.name()}, delete${entityMapper.code}.getIds());

		modelBuilder.putTrue(ModelBuilder.Constants.whereAndBetween.stringValue(), CommonDtoAttributes.sysdate.name());

		return this.jdbcTemplateSupport.update(SqlIds.deleteByIds.id(), modelBuilder.build());
	}
</#if>

	@Override
	@CacheEvict(value = ${entityCode}Dao.BEAN_ID, allEntries = true)
	public int updateByCode(@NonNull ${entityMapper.code}Dto update${entityMapper.code}, String[] updateProperties, String... whereAndEqProperties) {
		final ModelBuilder modelBuilder = ModelBuilderUtils.newModelBuilder(new ModelArgs(ModelBuilder.Constants.update.stringValue(),
				update${entityMapper.code}, updateProperties), new ModelArgs(update${entityMapper.code}, whereAndEqProperties));

		if (!(ArrayUtils.contains(whereAndEqProperties, CommonDtoAttributes.beginDate.name()) || ArrayUtils
				.contains(whereAndEqProperties, CommonDtoAttributes.endDate.name()))) {
			modelBuilder.putTrue(ModelBuilder.Constants.whereAndBetween.stringValue(), CommonDtoAttributes.sysdate.name());
		}

		return this.jdbcTemplateSupport.update(SqlIds.updateByCode.id(), modelBuilder.build());
	}
<#if entityMapper.markService>

	@Override
	@CacheEvict(value = ${entityCode}Dao.BEAN_ID, allEntries = true)
	public int updateByCodeOrId(@NonNull ${entityMapper.code}Dto update${entityMapper.code}) {
		final ModelBuilder modelBuilder = ModelBuilderUtils.newModelBuilder(new ModelArgs(update${entityMapper.code}));

		modelBuilder.putTrue(ModelBuilder.Constants.whereAndBetween.stringValue(), CommonDtoAttributes.sysdate.name());

		return this.jdbcTemplateSupport.update(SqlIds.updateByCode.id(), modelBuilder.build());
	}
	
	@Override
	@CacheEvict(value = ${entityCode}Dao.BEAN_ID, allEntries = true)
	public int updateByIds(@NonNull ${entityMapper.code}Dto update${entityMapper.code}) {
		ModelBuilder modelBuilder = ModelBuilderUtils.newModelBuilder();

		modelBuilder.put(new String[] { CommonDtoAttributes.endDate.name() }, new DateTime().plusSeconds(-1));

		modelBuilder.put(new String[] { DtoAttributes.ids.name() }, update${entityMapper.code}.getIds());

		modelBuilder.putTrue(ModelBuilder.Constants.whereAndBetween.stringValue(), CommonDtoAttributes.sysdate.name());

		return this.jdbcTemplateSupport.update(SqlIds.updateByIds.id(), modelBuilder.build());
	}
</#if>

	@Override
	@Cacheable(value = ${entityCode}Dao.BEAN_ID, key = com.cardone.common.cache.Constants.KEY_4)
	public <R> R readByCode(@NonNull Class<R> requiredType, String objectId, @NonNull ${entityMapper.code}Dto read${entityMapper.code},
			String... whereAndEqProperties) {
		final ModelBuilder modelBuilder = ModelBuilderUtils.newModelBuilder(new ModelArgs(read${entityMapper.code},
				whereAndEqProperties));

		if (!(ArrayUtils.contains(whereAndEqProperties, CommonDtoAttributes.beginDate.name()) || ArrayUtils
				.contains(whereAndEqProperties, CommonDtoAttributes.endDate.name()))) {
			modelBuilder.putTrue(ModelBuilder.Constants.whereAndBetween.stringValue(), CommonDtoAttributes.sysdate.name());
		}

		return this.jdbcTemplateSupport.read(requiredType, SqlIds.readByCode.id(), objectId,
				modelBuilder.build());
	}
<#if entityMapper.markService>

	@Override
	@Cacheable(value = ${entityCode}Dao.BEAN_ID, key = com.cardone.common.cache.Constants.KEY_3)
	public <R> R readByCodeOrId(@NonNull Class<R> requiredType, String objectId, @NonNull ${entityMapper.code}Dto read${entityMapper.code}) {
		final ModelBuilder modelBuilder = ModelBuilderUtils.newModelBuilder(new ModelArgs(read${entityMapper.code}));

		modelBuilder.putTrue(ModelBuilder.Constants.whereAndBetween.stringValue(), CommonDtoAttributes.sysdate.name());

		return this.jdbcTemplateSupport.read(requiredType, SqlIds.readByCode.id(), objectId,
				modelBuilder.build());
	}

	@Override
	@Cacheable(value = ${entityCode}Dao.BEAN_ID, key = com.cardone.common.cache.Constants.KEY_3)
	public <R> R readByName(@NonNull Class<R> requiredType, String objectId, @NonNull ${entityMapper.code}Dto read${entityMapper.code}) {
		final ModelBuilder modelBuilder = ModelBuilderUtils.newModelBuilder(new ModelArgs(read${entityMapper.code}));

		modelBuilder.putTrue(ModelBuilder.Constants.whereAndBetween.stringValue(), CommonDtoAttributes.sysdate.name());

		return this.jdbcTemplateSupport.read(requiredType, SqlIds.readByName.id(), objectId,
				modelBuilder.build());
	}
</#if>

	@Override
	@Cacheable(value = ${entityCode}Dao.BEAN_ID, key = com.cardone.common.cache.Constants.KEY_4)
	public <R> List<R> readListByCode(@NonNull Class<R> requiredType, String objectId, @NonNull ${entityMapper.code}Dto readList${entityMapper.code},
			String... whereAndEqProperties) {
		final ModelBuilder modelBuilder = ModelBuilderUtils.newModelBuilder(new ModelArgs(readList${entityMapper.code},
				whereAndEqProperties));

		if (!(ArrayUtils.contains(whereAndEqProperties, CommonDtoAttributes.beginDate.name()) || ArrayUtils
				.contains(whereAndEqProperties, CommonDtoAttributes.endDate.name()))) {
			modelBuilder.putTrue(ModelBuilder.Constants.whereAndBetween.stringValue(), CommonDtoAttributes.sysdate.name());
		}

		return this.jdbcTemplateSupport.readList(requiredType, SqlIds.readByCode.id(), objectId,
				modelBuilder.build());
	}
<#if entityMapper.markService>

	@Override
	@Cacheable(value = ${entityCode}Dao.BEAN_ID, key = com.cardone.common.cache.Constants.KEY_3)
	public <R> List<R> readListByCodeOrId(@NonNull Class<R> requiredType, String objectId, @NonNull ${entityMapper.code}Dto readList${entityMapper.code}) {
		final ModelBuilder modelBuilder = ModelBuilderUtils.newModelBuilder(new ModelArgs(readList${entityMapper.code}));

		modelBuilder.putTrue(ModelBuilder.Constants.whereAndBetween.stringValue(), CommonDtoAttributes.sysdate.name());

		return this.jdbcTemplateSupport.readList(requiredType, SqlIds.readByCode.id(), objectId,
				modelBuilder.build());
	}

	@Override
	@Cacheable(value = ${entityCode}Dao.BEAN_ID, key = com.cardone.common.cache.Constants.KEY_3)
	public <R> List<R> readListByName(@NonNull Class<R> requiredType, String objectId, @NonNull ${entityMapper.code}Dto readList${entityMapper.code}) {
		final ModelBuilder modelBuilder = ModelBuilderUtils.newModelBuilder(new ModelArgs(readList${entityMapper.code}));

		modelBuilder.putTrue(ModelBuilder.Constants.whereAndBetween.stringValue(), CommonDtoAttributes.sysdate.name());

		return this.jdbcTemplateSupport.readList(requiredType, SqlIds.readByName.id(), objectId,
				modelBuilder.build());
	}
</#if>

	@Override
	@Cacheable(value = ${entityCode}Dao.BEAN_ID, key = com.cardone.common.cache.Constants.KEY_4)
	public <P> P findByCode(@NonNull Class<P> mappedClass, @NonNull ${entityMapper.code}Dto find${entityMapper.code},
			String[] selectProperties, String... whereAndEqProperties) {
		final ModelBuilder modelBuilder = ModelBuilderUtils.newModelBuilder(new ModelArgs(find${entityMapper.code},
				whereAndEqProperties));

		modelBuilder.putTrueExtend(ModelBuilder.Constants.select.stringValue(), selectProperties);

		if (!(ArrayUtils.contains(whereAndEqProperties, CommonDtoAttributes.beginDate.name()) || ArrayUtils
				.contains(whereAndEqProperties, CommonDtoAttributes.endDate.name()))) {
			modelBuilder.putTrue(ModelBuilder.Constants.whereAndBetween.stringValue(), CommonDtoAttributes.sysdate.name());
		}

		return this.jdbcTemplateSupport.find(mappedClass, SqlIds.findByCode.id(),
				modelBuilder.build());
	}
<#if entityMapper.markService>

	@Override
	@Cacheable(value = ${entityCode}Dao.BEAN_ID, key = com.cardone.common.cache.Constants.KEY_2)
	public <P> P findByCodeOrId(@NonNull Class<P> mappedClass, @NonNull ${entityMapper.code}Dto find${entityMapper.code}) {
		final ModelBuilder modelBuilder = ModelBuilderUtils.newModelBuilder(new ModelArgs(find${entityMapper.code}));

		modelBuilder.putTrue(ModelBuilder.Constants.whereAndBetween.stringValue(), CommonDtoAttributes.sysdate.name());

		return this.jdbcTemplateSupport.find(mappedClass, SqlIds.findByCode.id(),
				modelBuilder.build());
	}

	@Override
	@Cacheable(value = ${entityCode}Dao.BEAN_ID, key = com.cardone.common.cache.Constants.KEY_2)
	public <P> P findByName(@NonNull Class<P> mappedClass, @NonNull ${entityMapper.code}Dto find${entityMapper.code}) {
		final ModelBuilder modelBuilder = ModelBuilderUtils.newModelBuilder(new ModelArgs(find${entityMapper.code}));

		modelBuilder.putTrue(ModelBuilder.Constants.whereAndBetween.stringValue(), CommonDtoAttributes.sysdate.name());

		return this.jdbcTemplateSupport.find(mappedClass, SqlIds.findByName.id(),
				modelBuilder.build());
	}

	@Override
	@Cacheable(value = ${entityCode}Dao.BEAN_ID, key = com.cardone.common.cache.Constants.KEY_2)
	public <R> R readByCodeNqId(@NonNull Class<R> requiredType, @NonNull ${entityMapper.code}Dto read${entityMapper.code}) {
		final ModelBuilder modelBuilder = ModelBuilderUtils.newModelBuilder();

//		final ModelBuilder modelBuilder = ModelBuilderUtils.newModelBuilder().putExtend(null, CommonDtoAttributes.code.name(), null,
//				read${entityMapper.code}.getCode());

//		if (StringUtils.isNotBlank(read${entityMapper.code}.getId())) {
//			modelBuilder.putExtend(ModelBuilder.WHERE_AND_NQ, CommonDtoAttributes.id.name(), null, read${entityMapper.code}.getId());
//		}

		modelBuilder.putTrue(ModelBuilder.Constants.whereAndBetween.stringValue(), CommonDtoAttributes.sysdate.name());

		return this.jdbcTemplateSupport.read(requiredType, SqlIds.readByCode.id(), null,
				modelBuilder.build());
	}
</#if>

	@Override
	@Cacheable(value = ${entityCode}Dao.BEAN_ID, key = com.cardone.common.cache.Constants.KEY_4)
	public <P> List<P> findListByCode(@NonNull Class<P> mappedClass, @NonNull ${entityMapper.code}Dto findList${entityMapper.code},
			String[] selectProperties, String... whereAndEqProperties) {
		final ModelBuilder modelBuilder = ModelBuilderUtils.newModelBuilder(new ModelArgs(findList${entityMapper.code},
				whereAndEqProperties));

		modelBuilder.putTrueExtend(ModelBuilder.Constants.select.stringValue(), selectProperties);

		if (!(ArrayUtils.contains(whereAndEqProperties, CommonDtoAttributes.beginDate.name()) || ArrayUtils
				.contains(whereAndEqProperties, CommonDtoAttributes.endDate.name()))) {
			modelBuilder.putTrue(ModelBuilder.Constants.whereAndBetween.stringValue(), CommonDtoAttributes.sysdate.name());
		}

		return this.jdbcTemplateSupport.findList(mappedClass, SqlIds.findByCode.id(),
				modelBuilder.build());
	}
<#if entityMapper.markService>

	@Override
	@Cacheable(value = ${entityCode}Dao.BEAN_ID, key = com.cardone.common.cache.Constants.KEY_2)
	public <P> List<P> findListByCodeOrId(@NonNull Class<P> mappedClass, @NonNull ${entityMapper.code}Dto findList${entityMapper.code}) {
		final ModelBuilder modelBuilder = ModelBuilderUtils.newModelBuilder(new ModelArgs(findList${entityMapper.code}));

		modelBuilder.putTrue(ModelBuilder.Constants.whereAndBetween.stringValue(), CommonDtoAttributes.sysdate.name());

		return this.jdbcTemplateSupport.findList(mappedClass, SqlIds.findByCode.id(),
				modelBuilder.build());
	}

	@Override
	@Cacheable(value = ${entityCode}Dao.BEAN_ID, key = com.cardone.common.cache.Constants.KEY_2)
	public <P> List<P> findListByName(@NonNull Class<P> mappedClass, @NonNull ${entityMapper.code}Dto findList${entityMapper.code}) {
		final ModelBuilder modelBuilder = ModelBuilderUtils.newModelBuilder(new ModelArgs(findList${entityMapper.code}));

		modelBuilder.putTrue(ModelBuilder.Constants.whereAndBetween.stringValue(), CommonDtoAttributes.sysdate.name());

		return this.jdbcTemplateSupport.findList(mappedClass, SqlIds.findByName.id(),
				modelBuilder.build());
	}
<#if entityMapper.markController>

	@Override
	@Cacheable(value = ${entityCode}Dao.BEAN_ID, key = com.cardone.common.cache.Constants.KEY_2)
	public <P> PaginationDto<P> paginationByCode(@NonNull Class<P> mappedClass,
				@NonNull ${entityMapper.code}Dto pagination${entityMapper.code}) {
		final ModelBuilder modelBuilder = ModelBuilderUtils.newModelBuilder(new ModelArgs(pagination${entityMapper.code}));

		modelBuilder.putTrue(ModelBuilder.Constants.whereAndBetween.stringValue(), CommonDtoAttributes.sysdate.name());

		return this.jdbcTemplateSupport.pagination(mappedClass, new PaginationArgs(SqlIds.readByCode.id(),
				SqlIds.findByCode.id(),
				pagination${entityMapper.code}.getPaginationNo(),
				pagination${entityMapper.code}.getPaginationSize()),
				modelBuilder.build());
	}

	@Override
	@Cacheable(value = ${entityCode}Dao.BEAN_ID, key = com.cardone.common.cache.Constants.KEY_1)
	public PaginationDto<Map<String, Object>> paginationByName(@NonNull ${entityMapper.code}Dto pagination${entityMapper.code}) {
		final ModelBuilder modelBuilder = ModelBuilderUtils.newModelBuilder(new ModelArgs(pagination${entityMapper.code}));

		modelBuilder.putTrue(ModelBuilder.Constants.whereAndBetween.stringValue(), CommonDtoAttributes.sysdate.name());

		return this.jdbcTemplateSupport.pagination(new PaginationArgs(SqlIds.readByCode.id(),
				SqlIds.findByCode.id(),
				pagination${entityMapper.code}.getPaginationNo(),
				pagination${entityMapper.code}.getPaginationSize()),
				modelBuilder.build());
	}
</#if>
</#if>
}